home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / NDK / NDK_3.5 / Tutorials / ARexx / FunctionLibrary / Source / libbase.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-04  |  5.3 KB  |  251 lines

  1. /*
  2.  * $Id: libbase.c 1.1 1997/06/25 18:46:44 olsen Exp $
  3.  *
  4.  * ARexx sample library
  5.  *
  6.  * :ts=4
  7.  */
  8.  
  9. #include "rexxsamplebase.h"
  10. #include "rexxsample.library_rev.h"
  11.  
  12. /****************************************************************************/
  13.  
  14.     /* This will be the first function of this library. It must return
  15.      * an error to the caller.
  16.      */
  17.  
  18. LONG ReturnError(VOID) { return(-1); }
  19.  
  20. /****************************************************************************/
  21.  
  22.     /* LibInit():
  23.      *
  24.      *    This is a standard library initialization routine written
  25.      *    in `C'. It opens two rom-resident libraries (dos.library
  26.      *    and utility.library), the third required library being
  27.      *    disk-based. It will be opened in LibOpen().
  28.      */
  29.  
  30. STATIC struct RexxSampleBase * ASM
  31. LibInit(
  32.     REG(d0) struct RexxSampleBase *    RexxSampleBase,
  33.     REG(a0) BPTR                    Segment,
  34.     REG(a6) struct ExecBase *        ExecBase)
  35. {
  36.     struct RexxSampleBase * result = NULL;
  37.  
  38.         /* We must initialize this for the library open calls to work. */
  39.  
  40.     SysBase = ExecBase;
  41.  
  42.     DOSBase        = OpenLibrary("dos.library",37);
  43.     UtilityBase    = OpenLibrary("utility.library",37);
  44.  
  45.         /* Did the two libraries open? */
  46.  
  47.     if(DOSBase != NULL && UtilityBase != NULL)
  48.     {
  49.         result = RexxSampleBase;
  50.  
  51.             /* Initialize the revision number; all other information
  52.              * will have been initialized by the library loader,
  53.              * using the data in the Resident tag.
  54.              */
  55.  
  56.         RexxSampleBase->rsb_Library.lib_Revision = REVISION;
  57.  
  58.         RexxSampleBase->rsb_Segment = Segment;
  59.  
  60.         InitSemaphore(&RexxSampleBase->rsb_Semaphore);
  61.     }
  62.     else
  63.     {
  64.         if(DOSBase != NULL)
  65.             CloseLibrary(DOSBase);
  66.  
  67.         if(UtilityBase != NULL)
  68.             CloseLibrary(UtilityBase);
  69.  
  70.             /* Important: The library base and the jump table
  71.              *            vector must be freed if this auto-init
  72.              *            routine fails.
  73.              */
  74.  
  75.         FreeMem((BYTE *)RexxSampleBase - RexxSampleBase->rsb_Library.lib_NegSize,
  76.                 RexxSampleBase->rsb_Library.lib_NegSize + RexxSampleBase->rsb_Library.lib_PosSize);
  77.     }
  78.  
  79.     return(result);
  80. }
  81.  
  82.     /* LibOpen():
  83.      *
  84.      *    The library open routine; the first caller to open the
  85.      *    library will also open the disk-resident rexxsyslib.library.
  86.      */
  87.  
  88. STATIC struct RexxSampleBase * ASM
  89. LibOpen(REG(a6) struct RexxSampleBase * RexxSampleBase)
  90. {
  91.     struct RexxSampleBase * result = NULL;
  92.     UWORD openCnt;
  93.  
  94.     openCnt = RexxSampleBase->rsb_Library.lib_OpenCnt;
  95.  
  96.     RexxSampleBase->rsb_Library.lib_Flags &= ~LIBF_DELEXP;
  97.     RexxSampleBase->rsb_Library.lib_OpenCnt++;
  98.  
  99.         /* Start of critical section. */
  100.  
  101.     ObtainSemaphore(&RexxSampleBase->rsb_Semaphore);
  102.  
  103.     if(openCnt == 0)
  104.         RexxSysBase = OpenLibrary(RXSNAME,0);
  105.  
  106.     ReleaseSemaphore(&RexxSampleBase->rsb_Semaphore);
  107.  
  108.         /* End of critical section. */
  109.  
  110.     if(RexxSysBase != NULL)
  111.     {
  112.         result = RexxSampleBase;
  113.     }
  114.     else
  115.     {
  116.         RexxSampleBase->rsb_Library.lib_OpenCnt--;
  117.     }
  118.  
  119.     return(result);
  120. }
  121.  
  122. STATIC BPTR ASM
  123. LibExpunge(REG(a6) struct RexxSampleBase *RexxSampleBase)
  124. {
  125.     BPTR result = NULL;
  126.  
  127.     if(RexxSampleBase->rsb_Library.lib_OpenCnt == 0)
  128.     {
  129.         result = RexxSampleBase->rsb_Segment;
  130.  
  131.         CloseLibrary(DOSBase);
  132.         CloseLibrary(UtilityBase);
  133.  
  134.         Remove(RexxSampleBase);
  135.  
  136.         FreeMem((BYTE *)RexxSampleBase - RexxSampleBase->rsb_Library.lib_NegSize,
  137.                 RexxSampleBase->rsb_Library.lib_NegSize + RexxSampleBase->rsb_Library.lib_PosSize);
  138.     }
  139.     else
  140.     {
  141.         RexxSampleBase->rsb_Library.lib_Flags |= LIBF_DELEXP;
  142.     }
  143.  
  144.     return(result);
  145. }
  146.  
  147. STATIC BPTR ASM
  148. LibClose(REG(a6) struct RexxSampleBase *RexxSampleBase)
  149. {
  150.     BPTR result = NULL;
  151.  
  152.         /* Start of critical section. */
  153.  
  154.     ObtainSemaphore(&RexxSampleBase->rsb_Semaphore);
  155.  
  156.         /* Close rexxsyslib.library if this the
  157.          * last customer.
  158.          */
  159.  
  160.     if(RexxSampleBase->rsb_Library.lib_OpenCnt == 1)
  161.     {
  162.         if(RexxSysBase != NULL)
  163.         {
  164.             CloseLibrary(RexxSysBase);
  165.             RexxSysBase = NULL;
  166.         }
  167.     }
  168.  
  169.     ReleaseSemaphore(&RexxSampleBase->rsb_Semaphore);
  170.  
  171.         /* End of critical section. */
  172.  
  173.     RexxSampleBase->rsb_Library.lib_OpenCnt--;
  174.  
  175.     if(RexxSampleBase->rsb_Library.lib_OpenCnt == 0 && (RexxSampleBase->rsb_Library.lib_Flags & LIBF_DELEXP))
  176.         result = LibExpunge(RexxSampleBase);
  177.  
  178.     return(result);
  179. }
  180.  
  181. STATIC LONG
  182. LibNull(VOID)
  183. {
  184.     return(NULL);
  185. }
  186.  
  187. /****************************************************************************/
  188.  
  189.     /* Defined in glue.a */
  190.  
  191. LONG ASM RexxDispatchGlue(REG(a0) struct RexxMsg *);
  192.  
  193. /****************************************************************************/
  194.  
  195.     /* Library initialization table data; first the four mandatory
  196.      * functions, then the only user function.
  197.      */
  198.  
  199. APTR LibVectors[] =
  200. {
  201.     LibOpen,
  202.     LibClose,
  203.     LibExpunge,
  204.     LibNull,
  205.  
  206.     RexxDispatchGlue,
  207.  
  208.     (APTR)-1
  209. };
  210.  
  211.     /* This will allocate memory for the library base and make
  212.      * the library ready to use before the init routine is called.
  213.      */
  214.  
  215. typedef struct Library * (* LIBINIT)();
  216.  
  217. struct LibInit
  218. {
  219.     ULONG                li_StructureSize;        /* Size of the library structure. */
  220.     APTR *                li_FunctionTable;        /* Library function table. */
  221.     struct LibData *    li_StructureInitTable;    /* Library base initialization table. */
  222.     LIBINIT                li_InitRoutine;            /* Library initialization routine. */
  223. };
  224.  
  225. STATIC struct LibInit LibraryInit =
  226. {
  227.     sizeof(struct RexxSampleBase),
  228.     LibVectors,
  229.     NULL,
  230.     (LIBINIT)LibInit
  231. };
  232.  
  233.     /* The library loader searches for the following data
  234.      * structure. It is responsible for initializing and
  235.      * configuring the library base and library function table.
  236.      */
  237.  
  238. struct Resident LibraryTag =
  239. {
  240.     RTC_MATCHWORD,
  241.     &LibraryTag,
  242.     &LibraryTag + 1,
  243.     RTF_AUTOINIT,
  244.     VERSION,
  245.     NT_LIBRARY,
  246.     0,
  247.     "rexxsample.library",
  248.     VSTRING,
  249.     &LibraryInit
  250. };
  251.